<?php

class Mozg_Lang_Instance
{
	protected $_queue;

	public function __construct($langPath)
	{
		$this->InitQueue();

		$this->SetLangPath($langPath);
		$this->Required('default');
	}

	protected function InitQueue()
	{
		if (is_array($this->_queue)) return;
		$this->_queue = array();
	}

	protected function QueuePush($value)
	{
		$this->_queue[] = $value;
		return $this;
	}

	protected function QueuePop()
	{
		return array_shift($this->_queue);
	}

	protected function CountQueue()
	{
		return count($this->_queue);
	}

	private $_langData = array();

	public function Translate($text, $params, $isDebug = null)
	{
		$upperText = strtoupper($text);

		while (!isset($this->_langData[$upperText]) && $this->LoadNext())
		{
			//do nothing
		}

		if (isset($this->_langData[$upperText]))
		{
			$text = $this->_langData[$upperText];
		}
		else if ($isDebug)
		{
			$this->CreateTextPlaceholder($text);
			$text = '••' .$text. '••';
		}

		if (is_array($params) && sizeof($params))
		{
			array_unshift($params, $text);
			$text = call_user_func_array('sprintf', $params);
		}

		return $text;
	}

	private $_packsLoaded = array();

	public function Required($packName = 'default')
	{
		if (!strlen($packName) || $this->_packsLoaded[$packName]) return;
		$this->_packsLoaded[$packName] = true;

		/*
		 * load untranslated files first
		 */
		$this->QueuePush('__' .$packName);

		$this->QueuePush($packName);
	}

	protected function LoadNext()
	{
		if (!$this->CountQueue()) return false;
		$packName = $this->QueuePop();

		$langFile = $this->GetLangPath().$packName;
		if (!Mozg_Storage::Exists($langFile))
		{
			return true;
		}

		$packData = array_change_key_case(Mozg_Storage::Read($langFile), CASE_UPPER);

		$this->_langData = (array)$packData + $this->_langData;
		return true;
	}

	private $_path = false;

	private function SetLangPath($path)
	{
		if (!is_dir($path)) throw new Mozg_Exception_System('Invalid lang path');
		$this->_path = rtrim($path, '/\\'). '/';
	}

	private function GetLangPath()
	{
		return $this->_path;
	}

	protected $_placeholders = array();

	protected function CreateTextPlaceholder($placeholder)
	{
		$fileName = false;

		$trace = debug_backtrace();
		foreach ($trace as $traceLine)
		{
			$class = $traceLine['class'];
			if (stripos($class, '_Ctrl_'))
			{
				if (preg_match('#Module_([^_]+)_Component_([^_]+)_Ctrl#is', $class, $matches))
				{
					$fileName = 'module_' .$matches[1]. '_ctrl_' .$matches[2];
				}
			}
			else if (stripos($class, '_Mapper'))
			{
				if (preg_match('#Source_([^_]+)_Mapper#is', $class, $matches))
				{
					$fileName = 'mapper_' .$matches[1];
				}
			}
			else if (stripos($class, '_Module_'))
			{
				if (preg_match('#Module_([^_]+)_Module#is', $class, $matches))
				{
					$fileName = 'module_' .$matches[1];
				}
			}

			if ($fileName != false) break;
		}

		if ($fileName == false) $fileName = 'default';

		$this->_placeholders['__' .strtolower($fileName)][$placeholder] = $placeholder;
	}

	public function __destruct()
	{
		if (!sizeof($this->_placeholders)) return;

		foreach ($this->_placeholders as $packName => $packData)
		{
			$packData = array_change_key_case($packData, CASE_UPPER);

			$langFile = $this->GetLangPath().$packName;
			if (Mozg_Storage::Exists($langFile))
			{
				$packData += array_change_key_case(Mozg_Storage::Read($langFile), CASE_UPPER);
			}

			Mozg_Storage::Save($langFile, $packData);
		}
	}
}